using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;

namespace FastPoster.DataProviders.DAO
{
    public class AbstractDAO
    {
        /// <summary>
        /// cac bien thanh phan thuc hien thao tac truy xuat CSDL
        /// </summary>
        protected String sql;//bien giu vai tro la cau lenh truy van
        protected OleDbConnection objConnection;
        protected OleDbCommand objCommand;
        protected OleDbDataAdapter objDataAdapter;
        protected OleDbDataReader objDataReader;
        //////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;
        public AbstractDAO(IntPtr handle)
        {
            this.handle = handle;
        }
        /// <summary>
        /// cac ham thuc hien thao tao huy(lay trong MSDN_khong can quan tam)
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue 
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }
        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the 
        // runtime from inside the finalizer and you should not reference 
        // other objects. Only unmanaged resources can be disposed.
        public void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed 
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up 
                // unmanaged resources here.
                // If disposing is false, 
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;
            }
            disposed = true;
        }

        // Use interop to call the method necessary  
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method 
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~AbstractDAO()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }
        //////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// truyen duong dan toi thuc muc chua database de thuc thi ket noi
        /// </summary>
        /// <param name="strPath"></param>
        public AbstractDAO(String strPath)
        {
            try
            {
                string objConnectionString = "provider=Microsoft.Jet.OLEDB.4.0;data source=" + strPath;

                objConnection = new OleDbConnection(objConnectionString);
            }
            catch (System.Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
        }
        /// <summary>
        /// Add parameter cho cau lenh truy van
        /// </summary>
        /// <param name="Name"></param> 
        /// <param name="Type"></param>
        /// <param name="Size"></param>
        /// <param name="Value"></param>
        public void AddParameter(string Name, OleDbType Type, int Size, object Value)
        {
            try
            {
                objCommand.Parameters.Add(Name, Type, Size).Value = Value;

            }
            catch (System.Exception OleDbExceptionErr)
            {
                throw new System.Exception(OleDbExceptionErr.Message,
                OleDbExceptionErr.InnerException);
            }
        }
        /// <summary>
        /// mo ket noi
        /// </summary>
        public void OpenConnection()
        {
            try
            {
                objConnection.Open();
            }
            catch (OleDbException OleDbExceptionErr)
            {
                throw new Exception(OleDbExceptionErr.Message, OleDbExceptionErr.InnerException);
            }
            catch (InvalidOperationException InvalidOperationExceptionErr)
            {
                throw new Exception(InvalidOperationExceptionErr.Message, InvalidOperationExceptionErr.InnerException);
            }
        }
        /// <summary>
        /// dong ket noi
        /// </summary>
        public void CloseConnection()
        {
            objConnection.Close();
        }
        /// <summary>
        /// Khoi tao cau lenh truy van
        /// </summary>
        public void InitializeCommand()
        {
            if (objCommand == null)
            {
                try
                {
                    objCommand = new OleDbCommand(sql, objConnection);
                    //See if this is a stored procedure
                    if (!sql.ToUpper().StartsWith("SELECT ")
                        && !sql.ToUpper().StartsWith("INSERT ")
                        && !sql.ToUpper().StartsWith("UPDATE ")
                        && !sql.ToUpper().StartsWith("DELETE "))
                    {
                        objCommand.CommandType = CommandType.StoredProcedure;
                    }
                }
                catch (System.Exception e)
                {
                    throw new Exception(e.Message, e.InnerException);
                }
            }
        }
        public void InitializeDataAdapter()
        {
            try
            {
                objDataAdapter = new OleDbDataAdapter();
                objDataAdapter.SelectCommand = objCommand;//lua chon cau lenh
            }
            catch (System.Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
        }
        /// <summary>
        /// do du lieu vao dataset
        /// </summary>
        /// <param name="daoDataSet"></param>
        /// <param name="TableName"></param>
        public void FillDataSet(ref DataSet daoDataSet, String TableName)
        {
            try
            {
                InitializeCommand();
                InitializeDataAdapter();
                objDataAdapter.Fill(daoDataSet, TableName);
            }
            catch (System.Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
            finally
            {
                objCommand.Dispose();
                objCommand = null;
                objDataAdapter.Dispose();
                objDataAdapter = null;
            }
        }
        /// <summary>
        /// do du lieu vao dataTable
        /// </summary>
        /// <param name="daoDataSet"></param>
        /// <param name="TableName"></param>
        public void FillDataTable(ref DataTable oDataTable)
        {
            try
            {
                InitializeCommand();
                InitializeDataAdapter();
                objDataAdapter.Fill(oDataTable);
            }
            catch (System.Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
            finally
            {
                objCommand.Dispose();
                objCommand = null;
                objDataAdapter.Dispose();
                objDataAdapter = null;
            }
        }
        /// <summary>
        /// thuc thi cau truy van
        /// </summary>
        /// <returns>thuc thi xong, dong ket noi tra ve 1 bao thanh cong</returns>
        public Boolean ExecuteStoredProcedure()
        {
            try
            {
                OpenConnection();
                if (objCommand.ExecuteNonQuery() != 0)
                {
                    CloseConnection();
                    return true;
                }
                else
                {
                    CloseConnection();
                    return false;//that bai
                }
            }
            catch (System.Exception e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
        }

        public void CleanUpObject()
        {
            if (objCommand != null)
            {
                objCommand.Dispose();
                objCommand = null;
            }
            if (objDataAdapter != null)
            {
                objDataAdapter.Dispose();
                objDataAdapter = null;
            }
        }
    }
}
